package test2;

//1. 定义抽象的饮料类，作为所有饮料及配料装饰的基类
abstract class Beverage {
 String description = "Unknown Beverage";

 public String getDescription() {
     return description;
 }

 public abstract double cost();
}

//2. 具体的饮料类，这里以咖啡为例
class Coffee extends Beverage {
 public Coffee() {
     description = "Simple Coffee";
 }

 @Override
 public double cost() {
     return 5.0;
 }
}

//3. 定义抽象的配料装饰者类，它同样继承自饮料类，因为配料本身也可以看作一种饮料
abstract class CondimentDecorator extends Beverage {
 public abstract String getDescription();
}

//4. 具体的配料装饰者类 - 牛奶，用于给饮料添加牛奶
class Milk extends CondimentDecorator {
 private Beverage beverage;

 public Milk(Beverage beverage) {
     this.beverage = beverage;
 }

 @Override
 public String getDescription() {
     return beverage.getDescription() + ", Milk";
 }

 @Override
 public double cost() {
     return beverage.cost() + 2.0;
 }
}

//5. 具体的配料装饰者类 - 糖，用于给饮料添加糖
class Sugar extends CondimentDecorator {
 private Beverage beverage;

 public Sugar(Beverage beverage) {
     this.beverage = beverage;
 }

 @Override
 public String getDescription() {
     return beverage.getDescription() + ", Sugar";
 }

 @Override
 public double cost() {
     return beverage.cost() + 1.0;
 }
}

//6. 测试装饰者模式
public class DecoratorPatternExample {
 public static void main(String[] args) {
     Beverage coffee = new Coffee();
     System.out.println(coffee.getDescription() + " costs $" + coffee.cost());

     // 给咖啡添加牛奶
     Beverage coffeeWithMilk = new Milk(coffee);
     System.out.println(coffeeWithMilk.getDescription() + " costs $" + coffeeWithMilk.cost());

     // 再给加了牛奶的咖啡添加糖
     Beverage coffeeWithMilkAndSugar = new Sugar(coffeeWithMilk);
     System.out.println(coffeeWithMilkAndSugar.getDescription() + " costs $" + coffeeWithMilkAndSugar.cost());
 }
}
